<?php

/*
	Class: Commerce_ProductadminController

	About: Author
		Tyler Vigeant

	About: License
		<http://communit.as/docs/license>
*/
class Commerce_ProductadminController extends Cts_Controller_Action_Admin {

	function init() {
		parent::init();
	}

	function indexAction() {
		$Catalog = new CommerceMagentoCatalog();
		$request = new Cts_Request($this->getRequest());
		
		$products = false;
		$filters = array();
		$q_fields = array('name');
		$storeView = $this->locale_code;
		
		$per_page_default = Cts_Registry::get('products_per_page');
		$per_page_options = array(
			10=>'10',
			20=>'20',
			50=>'50',
			75=>'75',
			100=>'100',
		);
		
		if( !in_array($per_page_default, $per_page_options) ){
			$per_page_options[ $per_page_default ] = (string)$per_page_default;
			ksort($per_page_options);
		}
		
		if( $request->has('per') && !in_array($request->per, $per_page_options) ){
			krsort($per_page_options);
			if( $request->per < current($per_page_options) ){
				$per_page_options[ $request->per ] = (string)$request->per;
			} else {
				## Limit the items per page to the highest value in the array above.
				$request->per = current($per_page_options);
			}
			ksort($per_page_options);
		}
		
		## Apply pagination to product listing
		$filters['__limit'] = ($request->has('per')) ? $request->per : $per_page_default;
		$filters['__page'] = $this->_request->getParam('page', 0);
		$filters['__no_children'] = true;
		
		$this->view->per_page = $filters['__limit'];
		$this->view->per_page_options = $per_page_options;

		if( $request->has('categories') && $request->categories!='all' ){
			$filters['category_ids']	= (is_string($request->categories)) ? explode(',',$request->categories) : $request->categories;
		}

		if( $request->has('q') ){
			foreach( $q_fields as $field ){
				$filters[$field]	= array( 'like' => "%{$request->q}%" );
			}
		}

		$products = $Catalog->getProducts($filters, $storeView);
		
		$per_page = $Catalog->pagination['products']['per'];
		$page = $Catalog->pagination['products']['current'];
		$total = $Catalog->pagination['products']['total'];
		$total_pages = ceil($total/$per_page)-1;

		$base_url = "/".$this->_request->getModuleName()."/".$this->_request->getControllerName()."/".$this->_request->getActionName();
		$url = $base_url;
		
		if($request->has('q') && !empty($request->q)){
			$url .= '/q/'.urlencode($request->q);
		}
		if($request->has('categories') && !empty($request->categories)){
			$url .= '/categories/' . ((is_string($request->categories)) ? urlencode($request->categories) : implode(',',$request->categories));
		}
		if($request->has('per') && !empty($request->per)){
			$url .= '/per/'.urlencode($request->per);
		}
		
		## Trying to access a page greater than the total number of pages
		if( $page > $total_pages ){
			$this->session->commerce_productadmin_index_url = $base_url;
			$this->_redirect($url.'/page/'.$total_pages.'/');
		} else {
			$this->session->commerce_productadmin_index_url = $url.'/page/'.$page.'/';
		}
		
		$this->makePager($page, $per_page, $total, $url);

		$final_products = array();
		$category_cache = array();
		
		foreach($products as $products_key => $product) {
			$id = $product['product_id'];

			$attributes = array('name', 'updated_at', 'created_at', 'status', 'bd_last_edited_by');

			$final_products[$id] = $Catalog->getProduct($id, $storeView, $attributes);
			$final_products[$id]['updated_at'] = date('j M Y', strtotime($final_products[$id]['updated_at']));
			
			if( !isset($final_products[$id]['bd_last_edited_by']) || empty($final_products[$id]['bd_last_edited_by']) ){
				$final_products[$id]['bd_last_edited_by'] = 'Unknown';
			} else {
				$final_products[$id]['bd_last_edited_by'] = ucwords($final_products[$id]['bd_last_edited_by']);
			}
			
			if(is_array($final_products[$id]['categories'])){
				foreach( $final_products[$id]['categories'] as $key=>$value ){
					if( !array_key_exists($value, $category_cache) ){
						$lineage = Commerce_Common::categoryTree_single( $value );
						$category_cache[$value] = $lineage;
						$final_products[$id]['categories'][$key] = $lineage;
					} else {
						$final_products[$id]['categories'][$key] = $category_cache[$value];
					}
				}
			}
		}
		
		## SMARTY: Product List
		$this->view->product_list = $final_products;
		$this->view->no_products = (empty($final_products)) ? true : false;
		
		## SMARTY: Category Tree select menu options
		$all = array('all'=>$this->_T('Show all categories'));
		$tree = Commerce_Common::categoryTree_to_Options();
		$this->view->category_tree_options = Commerce_Common::simple_array_merge($all, $tree);
		$this->view->category_tree_options_selected = ($request->has('categories')) ? $request->categories : 'all';
		
		## SMARTY: Current user
		$this->view->current_user = $this->_identity->full_name;
		
		## SMARTY: Search Query
		$this->view->q = ($request->has('q')) ? $request->q : '';
		
		## SMARTY: Local vs. Global
		## FORCE GLOBAL EDITING FOR NOW
		$this->session->_editing_default_product_values = 1;
		if(Cts_ExtraResourceCheck::isAllowed("can_make_global_product_edits","commerce",$this->_identity->username)) {
			$this->view->_editing_default = array(
				//'0' => $this->_T('Edit Local Values'),
				'1' => $this->_T('Edit Default Values'),
			);
			$this->view->_editing_default_selected = 1; //(int)$this->session->_editing_default_product_values;
		}
	}
	
	function editAction() {
		$exec_time = ini_get('max_execution_time');
		Cts_Log::report("Max Execution Time :: Execution time is set to {$exec_time} seconds", NULL, Zend_Log::INFO);
		
		$errors = array();
		$Catalog = new CommerceMagentoCatalog();
		$request = new Cts_Request($this->getRequest());
		$cache_instance = new Commerce_Cache();
		$this->cache = $cache_instance->factory;
		
		## FORCE GLOBAL EDITING FOR NOW
		$this->session->_editing_default_product_values = 1;
		
		if( @Cts_ExtraResourceCheck::isAllowed("can_make_global_product_edits","commerce",$this->_identity->username)
		&& $this->session->_editing_default_product_values==true ) {
			$storeView = 0;
		} else {
			$this->session->_editing_default_product_values = false;
			$storeView = $this->locale_code;
		}
			
		if( !@Cts_ExtraResourceCheck::isAllowed("can_create_new_products","commerce",$this->_identity->username) ) {
			$errors = array('You are not allowed to edit this product.');
			$this->view->errors = $errors;
			$this->view->edit_allowed = false;
		} else {
			$this->view->edit_allowed = true;
			
			## IF WE ARE SAVING A PRODUCT
			if( $this->getRequest()->isPost() and $request->has('name') ){
				$defaults = array();
				if( $request->has('defaults') && is_array($request->defaults) ){
					$defaults = array_keys($request->defaults);
				}
				
				$form_only_attributes = array('_continue_editing','product_id','_product_type','_attribute_set','defaults','bd_media_title','bd_media_type','bd_media_color','bd_media_filename','bd_media_thumb','bd_media_add','child_sku','child_price','child_special_price','child_weight','product_search','product_relate_url','bd_award_title','bd_award_filename','submit','id','action','controller','module','locale');
				
				$request_attributes = array();
				foreach( $request as $code=>$attribute ){
					if( in_array($code, $defaults) ){
						$request_attributes[$code] = NULL;
						
					} elseif( !in_array($code, $form_only_attributes) ){
						switch($code){
							case 'bd_media':
								$media = array(); $x=0;
								foreach( $attribute as $media_item ){
									$media[$x]['sort_order']= ($x+1);
									$media[$x]['title']		= stripslashes($media_item['title']);
									$media[$x]['type']		= stripslashes($media_item['type']);
									if( isset($media_item['color']) ){
										$media[$x]['color']	= stripslashes($media_item['color']);
									} else {
										$media[$x]['color']	= '';
									}
									$media[$x]['filename']	= stripslashes($media_item['filename']);
									$media[$x]['thumb'] 	= stripslashes($media_item['thumb']);
									$media[$x]['active'] 	= (array_key_exists('active',$media_item)) ? 1 : 0;
									$x++;
								}
								$request_attributes[$code] = $media;
								break;
							
							case 'bd_awards':
								$awards = array(); $x=0;
								foreach( $attribute as $award_item ){
									$awards[$x]['sort_order']= ($x+1);
									$awards[$x]['title']		= $award_item['title'];
									$awards[$x]['filename']	= $award_item['filename'];
									$awards[$x]['active'] 	= (array_key_exists('active',$award_item)) ? 1 : 0;
									$x++;
								}
								$request_attributes[$code] = $awards;
								break;
							
							case 'bd_tags':
								$tags = (is_string($attribute)) ? explode(',', $attribute) : $attribute;
								if( is_array($tags) && !empty($tags) ){
									foreach( $tags as $key=>$tag ){
										if(empty($tag)){
											unset($tags[$key]);
										} else {
											$tags[$key] = trim($tag);
										}
									}
								} else {
									$tags = array();
								}
								$request_attributes[$code] = implode(',', array_unique($tags));
								break;
							
							case 'price':
								$request_attributes[$code] = number_format((float)$attribute, 4, '.', '');
								break;
								
							case 'special_price':
								if( (float)$attribute <= 0 ){
									$request_attributes[$code] = '';
								} else {
									$request_attributes[$code] = number_format((float)$attribute, 4, '.', '');
								}
								break;
							
							case 'weight':
								$attribute = $attribute * 0.00220462262;
								$request_attributes[$code] = number_format((float)$attribute, 4, '.', '');
								break;
							
							case 'status':
								$request_attributes[$code] = ($attribute=='1') ? (string)'1' : (string)'2';
								break;
								
							default:
								$request_attributes[$code] = $attribute;
								break;
						}
					}
				}
				
				## Copy the cleaned up request attributes to a new array for Magento preperation
				$saving = $request_attributes;
				$saving_children = array();
				$saving_related = array();
				
				if(empty($saving['short_description'])) $saving['short_description'] = 'Short product description goes here.';
				if(!isset($saving['tax_class_id'])) $saving['tax_class_id'] = (string)"1";
				
				foreach( $saving as $code=>$attribute ){
					switch($code){
						case 'name':
						case 'sku':
						case 'price':
						case 'weight':
						case 'description':
						case 'short_description':
							if(empty($attribute) && !in_array($code, $defaults)){
								$errors[] = 'Must supply a value for '.ucwords(str_replace('_',' ',$code));
							}
							break;
						
						case 'bd_media':
						case 'bd_awards':
							if( is_array($attribute) && !empty($attribute) ){
								$saving[$code] = serialize($attribute);
							} else {
								if( $this->session->_editing_default_product_values ){
									$saving[$code] = '';
								} else {
									$saving[$code] = NULL;	## This will cause Magento to use the product's default value
								}
							}
							break;
						
						case 'children':
							$saving_children = $saving['children'];
							unset($saving['children']);
							break;
							
						case 'related':
							$saving_related = $saving[$code];
							unset($saving[$code]);
							break;
					}
				}
			
				## Be very sure that bd_is_for_sale does not default to no
				if( !array_key_exists('bd_is_for_sale', $saving)
				||  is_null($saving['bd_is_for_sale']) || strlen((string)$saving['bd_is_for_sale'])<=0
				||  $saving['bd_is_for_sale']!=='0' ){
					
					$saving['bd_is_for_sale'] = '1';
				}
				
				if( !array_key_exists('bd_pdp_promotion_status', $saving) || !$saving['bd_pdp_promotion_status']==='1' ){
					$saving['bd_pdp_promotion_status'] = '0';
				}
				
				## Check for NULL vs an empty string
				foreach( $saving as $code=>$attribute ){
					if( is_null($saving[$code]) && isset($_REQUEST[$code]) && !is_null($_REQUEST[$code]) ){
						$saving[$code] = '';
					}
				}
				
				if( $saving['status'] != '1' ){
					$saving['status'] = '2';
				}
				
				//$saving['bd_last_edited_by'] = 'why would you break this?';
				//if( $this->_auth->hasIdentity() ){
					//$this->_identity = $this->_auth->getIdentity();
					//$saving['bd_last_edited_by'] = $this->_identity->username;
				//} else {
					//$saving['bd_last_edited_by'] = NULL;
				//}
				
				## Try to save the product
				if( count($errors)<=0 ){
					## Creating a new product
					if( $request->id == -1 ){
						if( !empty($request->_product_type) && !empty($request->_attribute_set) ){
							## Get a list of all of the websites.
							$website_data = $Catalog->getWebsites();
							$websites = Commerce_Common::websitesToIdArray( $website_data );
							
							## Add the product to all websites with a status of DISABLED
							$user_set_status = $saving['status'];
							$saving['websites'] = $websites;
							$saving['status'] = (string)"2";
							$saving['tax_class_id'] = (string)"1";
							
							## Attempt to create the product
							$this->addTime( 6 );
							$_create_product = $Catalog->createProduct( $request->_product_type, $request->_attribute_set, $saving['sku'], $saving);
							
							if(!$_create_product){
								$errors[] = "Product creation failed for an unknown reason.";
							} else {
								## REMOVED: Set the product to the user defined status in the default website's default store
								//$saving['status'] = $user_set_status;
								//$default_store = (int)Commerce_Common::getDefaultStore( $website_data );
								//$this->addTime( 3 );
								//$Catalog->updateProduct( $_create_product, array('status'=>$user_set_status), $default_store );
								
								## Send the user on to edit this product
								$this->_redirect("/".$this->_request->getModuleName()."/".$this->_request->getControllerName()."/edit/id/{$_create_product}/");
							}
						}
						
					## Saving an existing product
					} else {
						## Update product
						$this->addTime( 6 );
						$_update_product = $Catalog->updateProduct( $request->id, $saving, $storeView );
						
						if(!$_update_product){
							$errors[] = "The product update failed for an unknown reason.";
						} else {
							## Cache is now cleared by the model
						}

						## Related products
						if( !empty($saving_related) ){
							$relations = array();
							$already_related_ids = array();
							$already_related = $Catalog->getLinkedProducts( $request->id, 'related' );
							
							if( is_array($already_related) ){
								foreach( $already_related as $related_product ){
									$already_related_ids[] = $related_product['product_id'];
								}
								
								foreach( $already_related as $related_product ){
									if( !in_array($related_product['product_id'], $saving_related) ){
										$this->addTime( 3 );
										$relations[] = $Catalog->removeLinkedProduct('related', $request->id, $related_product['product_id']);
									}
								}
							}
							
							$x=0;
							if( is_array($saving_related) && !empty($saving_related) ){
								foreach( $saving_related as $this_id ){
									if( !in_array($this_id, $already_related_ids) ){
										$this->addTime( 3 );
										$relations[] = $Catalog->setLinkedProduct('related', $request->id, $this_id, array('position' => $x));
										$x++;
									}
								}
							}
							
							if(in_array(false, $relations)){
								$errors[] = 'One or more product relations failed.';
							}
						}
						
						## Children products
						## This takes place after the full product data has been loaded below.
					}
				}
			}
			
		
			## Get the interface data for creating a new product
			if( $request->id == -1 ){
				## Grab a list of product types (limited to those allowed by the registry) and attribute sets
				$allowed_types = explode(',', Cts_Registry::get('magento_allowed_product_types'));
				$product_types = Commerce_Common::productTypesToOptions( $Catalog->getProductTypes(), $allowed_types );
				$attribute_sets = Commerce_Common::attributeSetsToOptions( $Catalog->getProductAttributeSets() );
				asort($attribute_sets);
				
				## Look for product type and attribute set and validate them
				$_product_type = ($request->has('product_types') && array_key_exists($request->product_types, $product_types)) ? $request->product_types : false;
				$_attribute_set = ($request->has('attribute_sets') && array_key_exists($request->attribute_sets, $attribute_sets)) ? $request->attribute_sets : false;
				
				if( !$_product_type || !$_attribute_set ){
					## Prompt for Product Type and Attribute Set if not already in the POST
					$this->view->errors = $errors;
					$this->view->new_product_step_one = true;
					$this->view->product_types = $product_types;
					$this->view->attribute_sets = $attribute_sets;
					return;
				} else {
					$this->view->new_product = true;
					$this->view->masthead = 'Creating A New Product';
					$this->view->new_product_step_one = false;
					$this->view->_product_type = $_product_type;
					$this->view->_attribute_set = $_attribute_set;
					list($groups, $info) = Commerce_Common::getAttributeSetDetails( $_attribute_set, $storeView );
				}
				
			## Get the interface data editing an existing product
			} else {
				## Do not allow access to simple products that are the children of a configurable product
				$parent_ids = $Catalog->getParentIds( $request->id );
				
				if( !empty($parent_ids) && count($parent_ids)>0 ){
					if( !is_null($this->session->commerce_productadmin_index_url) ){
						$this->_redirect( $this->session->commerce_productadmin_index_url );
					} else {
						$this->_redirect('/commerce/productadmin/');
					}
				} else {
					list($groups, $info, $details) = Commerce_Common::getProductAttributeDetails( $request->id, $storeView );
					$_product_type = $details['type'];
					
					## Get related products
					$related = $Catalog->getRelatedProducts( $details['id'] );
					$related = (is_array($related)) ? $related : array();

					## Get children products
					$num_attributes = 0;
					$children_sorting = array('attribute'=>'sku','direction'=>'asc');
					$children = ($details['type']=='configurable') ? $Catalog->getChildrenProducts( $details['id'], $storeView, NULL, $children_sorting ) : false;
					
					## Clean up children data
					## This takes place after any new children products have been created below
					
					## SMARTY
					$this->view->details = $details;
					$this->view->related = $related;
					$this->view->new_product = false;
					if( @Cts_ExtraResourceCheck::isAllowed("can_make_global_product_edits","commerce",$this->_identity->username)
					&& $this->session->_editing_default_product_values==true ) {
						$this->view->masthead = 'Editing default values for: '.$info['name']['value'];
					} else {
						$this->view->masthead = 'Editing: '.$info['name']['value'];
					}
				}
			}
		
			## Add/Remove Child Products
			if( isset($_update_product) && $_update_product!==false && $details['type']=='configurable' ){
				if( is_array($children) ){
					$already_children_ids = array();
					foreach( $children as $child ){
						$already_children_ids[] = $child['product_id'];
						
						## Remove child products that are not in the saving_children array
						$deleted_children = array();
						if( !array_key_exists($child['product_id'], $saving_children) ){
							$this->addTime( 8 );
							$deleted_children[] = $Catalog->removeProduct($child['product_id'], $details['id']);
						}
					}
				}
				
				$updated_child_id_array = array();
				$this->addTime( count($saving_children) );
				$updated_child_array = $Catalog->getChildrenProducts( $details['id'], $storeView );
				if( is_array($updated_child_array) ){
					foreach( $updated_child_array as $current_child ){
						$updated_child_id_array[] = $current_child['product_id'];
					}
				}

				$associated_children = array();
				$created_children = array();
				$corrected_children = array();
				if( is_array($saving_children) ){
					foreach( $saving_children as $this_id=>$new_child ){
						## Only randomly generated alpha (non-numeric) keys are new products
						if( ctype_alpha((string)$this_id) ){
							## Create a place to copy the parent data over
							$mage_new_child = array();
							$mage_new_child['websites'] = $details['websites'];
							$mage_new_child['categories'] = $details['categories'];
							
							foreach( $info as $code=>$attribute ){
								if( array_key_exists($code, $new_child) ){
									switch($code){
										case 'id':
											continue;
										
										case 'price':
											$mage_new_child[$code] = number_format((float)$new_child[$code], 4, '.', '');
											break;
											
										case 'weight':
											$new_child[$code] = $new_child[$code] * 0.00220462262;
											$mage_new_child[$code] = number_format((float)$new_child[$code], 4, '.', '');
											break;
										
										case 'special_price':
											if( (float)$new_child[$code]>0 ){
												$mage_new_child[$code] = number_format((float)$new_child[$code], 4, '.', '');
											} else {
												$mage_new_child[$code] = '';
											}
											break;
										
										default:
											$mage_new_child[$code] = $new_child[$code];
											break;
									}
								} else {
									## Strip out attributes that do not apply to simple products
									if( !in_array('simple', $attribute['apply_to']) && !empty($attribute['apply_to']) ){
										continue;
									}
									
									## Strip out filtering attributes
									if( isset($attribute['is_filterable']) && $attribute['is_filterable'] ){
										continue;
									}
									
									switch($code){
										case 'id':
										case 'updated_at':
										case 'created_at':
											continue;
										
										case 'bd_media':
										case 'bd_awards':
										case 'bd_tags':
											$mage_new_child[$code] = '';
											break;
										
										case 'status':
											$mage_new_child['status'] = 1;
											break;
											
										case 'visibility':
											$mage_new_child['visibility'] = 1;
											break;
											
										case 'description':
										case 'short_description':
											$mage_new_child[$code] = 'Please leave this line here for Magento.';
											break;
											
										case 'price':
										case 'weight':
										case 'special_price':
											$mage_new_child[$code] = number_format((float)$attribute['value'], 4, '.', '');
											break;
										
										default:
											if( $attribute['is_default']===false ){
												$mage_new_child[$code] = $attribute['default_value'];
											} else {
												$mage_new_child[$code] = $attribute['value'];
											}
											break;
									}
								}
							}
							
							## Be very sure that bd_is_for_sale does not default to no
							if( !array_key_exists('bd_is_for_sale', $mage_new_child)
							||  is_null($mage_new_child['bd_is_for_sale']) || strlen((string)$mage_new_child['bd_is_for_sale'])<=0
							||  $mage_new_child['bd_is_for_sale']!=='0' ){
								## Default to yes
								$mage_new_child['bd_is_for_sale'] = '1';
							}
							
							if( !array_key_exists('bd_pdp_promotion_status', $mage_new_child) || !$mage_new_child['bd_pdp_promotion_status']==='1' ){
								$mage_new_child['bd_pdp_promotion_status'] = '0';
							}
							
							$this->addTime( 5 );
							$created_child = $Catalog->createProduct( 'simple', $details['set'], $mage_new_child['sku'], $mage_new_child );
							
							if( $created_child!==false ){
								$created_children[] = true;
								$updated_child_id_array[] = $created_child;
								$associated_children[] = $Catalog->saveChildIds( $details['id'], $updated_child_id_array );
							} else {
								$created_children[] = false;
							}
							
						## If it is an existing child product, update the price
						## This is in place only to correct the issues created by the product importer
						} else {
							foreach( $updated_child_array as $check_child ){
								if( $check_child['product_id'] == $this_id ){
									$fix_child = array();
									
									if( isset($check_child['name'])
									&& $check_child['name'] != $saving['name']){
										$fix_child['name'] = $saving['name'];
									}
									
									if( !isset($check_child['price'])
									|| empty($check_child['price'])
									|| (float)$check_child['price']<=0){
										$fix_child['price'] = $saving['price'];
									}
									
									if( !isset($check_child['weight'])
									|| empty($check_child['weight'])
									|| (float)$check_child['weight']<=0 ){
										$fix_child['weight'] = $saving['weight'];
									}
									
									if( !isset($check_child['tax_class_id'])
									|| $check_child['tax_class_id']===''
									|| is_null($check_child['tax_class_id']) ){
										$fix_child['tax_class_id'] = 1;
									}
									
									if( !empty($fix_child)  ){
										$this->addTime( 7 );
										$updated_child = $Catalog->updateProduct( $this_id, $fix_child, $storeView );
										$corrected_children[] = (bool)$updated_child;
									}
									break;
								}
							}
						}
					}
				}
				
				if( in_array(false, $corrected_children) ){
					$errors[] = 'One or more of the product import corrections failed.';
				}
				
				if( in_array(false, $created_children) ){
					$errors[] = 'One or more of the child SKUs failed.';
				}
				
				if( in_array(false, $associated_children) ){
					$errors[] = 'One or more of the child SKUs were not associated to this product.';
				}
			}
			
			if( count($errors)<=0 && $request->has('_continue_editing') && $request->_continue_editing!='yes' ){
				if( !is_null($this->session->commerce_productadmin_index_url) ){
					$this->_redirect( $this->session->commerce_productadmin_index_url );
				} else {
					$this->_redirect('/commerce/productadmin/');
				}
			}
			
			## Turn the children array into a simple array of IDs
			if( isset($updated_child_id_array) && is_array($updated_child_id_array) ){
				## Replace the existing children array with the updated children array
				$children = $updated_child_id_array;
			} else {
				$tmp_children = array();
				foreach( $children as $child ){
					$tmp_children[] = $child['product_id'];
				}
				$children = $tmp_children;
			}
			
			## Clean up children array for use in Smarty
			if( is_array($children) && count($children)>0 ){
				foreach( $children as $key=>$child ){
					$children[$key] = Commerce_Common::getSimplifiedChildProduct( $child, $storeView, array($info['price']['value'], $info['special_price']['value']) );
					$children[$key]['weight'] = $children[$key]['weight'] * 453.59237;
					$children[$key]['weight'] = number_format($children[$key]['weight'], 0, '', '');
				}
				
				foreach( $children[0]['attributes'] as $code=>$attribute ){
					if( $code!='bd_color_swatch_one' && $code!='bd_color_swatch_two' ){
						$num_attributes++;
					}
				}
			} else {
				$num_attributes = 0;
			}
			
			## SMARTY
			$this->view->children = $children;
			$this->view->children_num_attributes = ($num_attributes+3);	## Number of attributes plus SKU, Price, and Action cols
			
			
			## Add request data back into the data pulled from Magento
			if( $this->getRequest()->isPost() && $request->has('name') && is_array($request_attributes) ){
				foreach( $info as $key => $attribute ){
					if( array_key_exists($key, $request_attributes) ){
						if( $request_attributes[$key]==NULL ){
							$info[$key]['is_default'] = true;
							
							if( isset($info[$key]['default_value']) ){
								$info[$key]['value'] = $info[$key]['default_value'];
							} elseif( isset($defaults[$key]) ){
								$info[$key]['value'] = $defaults[$key];
							} else {
								$info[$key]['value'] = NULL;
							}
						} else {
							$info[$key]['value'] = $request_attributes[$key];
						}
					}
				}
			}
			
			if( is_array($children) && count($children)>0 ){
				if( !isset($info['weight']['value']) || is_null($info['weight']['value']) || $info['weight']['value']==0 ){
					foreach( $children as $child ){
						if( isset($child['weight']) && !is_null($child['weight']) && $child['weight']>0 ){
							$info['weight']['value'] = $child['weight'] / 453.59237;
							break;
						}
					}
				}
			}
				
			## SMARTY: Prep variable for smarty use
			foreach( $info as $key => $attribute ){
				if( $attribute['code'] == 'status' ){
					if( $attribute['value'] != '1' ){
						$info[ $key ]['value'] = '2';
					}
					$info[ $key ]['options_smarty'] = array(
					 	'1' => 'Enabled',
						'2' => 'Disabled',
					 );
					
				} else if( isset($attribute['type']) && $attribute['type'] == 'boolean' ){
					if( is_null($info[ $key ]['value']) ){
						if( $attribute['code']=='bd_is_for_sale' ){
							$info[ $key ]['value'] = '1';
						} else {
							$info[ $key ]['value'] = '0';
						}
					}
					$info[ $key ]['options_smarty'] = array(
					 	'1' => 'Yes',
						'0' => 'No',
					 );
				
				} else if( $attribute['code']=='bd_media' || $attribute['code']=='bd_awards' ){
					if( is_string($info[ $key ]['value'])){
						$info[ $key ]['value'] = @unserialize( $info[ $key ]['value'] );
					}
					
					if( $attribute['code']=='bd_media' && is_array($info[$key]['value']) ){
						$options = $Catalog->getProductAttributeOptions( 951, $this->locale_code ); // TO-DO un-hard-code this.
						foreach( $info[$key]['value'] as &$item ){
							if( isset($item['color']) && is_array($options) ){
								foreach( $options as $option ){
									if( $option['value']==$item['color'] ){
										$item['color_name'] = $option['label'];
										break;
									}
								}
							}
						}
					}
					
				} else if( $attribute['code']=='weight' ){
					$info[ $key ]['value'] = $info[ $key ]['value'] * 453.59237;
					$info[ $key ]['value'] = number_format((float)$info[ $key ]['value'], 0, '', '');	
					
				} else if( $attribute['code'] == 'bd_tags' ){
					if( strpos($info[ $key ]['value'],'{') !== false ){
						$info[ $key ]['value'] = @unserialize( $info[ $key ]['value'] );
					} elseif( is_string($info[ $key ]['value'])){
						$info[ $key ]['value'] = explode(',', $info[ $key ]['value']);
					}
					
				} else if( isset($attribute['type']) && $attribute['type']=='select' && is_array($attribute['options']) ){
					$info[ $key ]['options_smarty'] = array(''=>'Select an option...');
					foreach( $attribute['options'] as $option ){
						$info[ $key ]['options_smarty'][ $option['value'] ] = $option['label'];
					}
				}
				
				if( isset($attribute['default_value']) && !is_null($attribute['default_value']) ){
					$info[ $key ]['default_value_smarty'] = str_replace('"', '\"', $attribute['default_value']);
				} else {
					$info[ $key ]['default_value_smarty'] = str_replace('"', '\"', $attribute['value']);
				}
			}
			
			## Reorder the contents of the General group
			$order = array_reverse(array('name','sku','price','special_price','weight','status','bd_is_for_sale','short_description','description','bd_features','bd_pdp_promotion_status','bd_pdp_promotion','bd_size_chart','bd_attachment_name','bd_attachment_file'));
			foreach( $groups as $group_key => $group ){
				if( trim($group['attribute_group_name']) == 'General' ){
					foreach( $order as $code ){
						foreach( $group['attributes'] as $attrib_key => $attrib ){
							if( $attrib['code'] == $code ){
								$tmp = $attrib;
								unset($group['attributes'][$attrib_key]);
								array_unshift($group['attributes'], $tmp);
								break;
							}
						}
					}
					
					$groups[$group_key] = $group;
					break;
				}
			}
			
			## SMARTY
			$this->view->category_tree_options = Commerce_Common::categoryTree_to_Options();
			$this->view->category_tree_options_selected = $details['categories'];
			$this->view->errors = $errors;
			$this->view->groups = $groups;
			$this->view->product = $info;
			$this->view->is_configurable = ($_product_type=='configurable') ? true : false;
			$this->view->is_editing_defaults = (int)$this->session->_editing_default_product_values;
		}
	}
	
	function setglobalAction(){
		$request = new Cts_Request($this->getRequest());
		if($request->has('edit_default') && Cts_ExtraResourceCheck::isAllowed("can_make_global_product_edits","commerce",$this->_identity->username)) {
			$this->session->_editing_default_product_values = (bool)$request->edit_default;
		}
	}
	
	function mediaitemAction(){
		$request = new Cts_Request($this->getRequest());
		if($request->has('title'))		$this->view->title = trim($request->title);
		if($request->has('type'))		$this->view->type = trim($request->type);
		if($request->has('filename'))	$this->view->filename = trim($request->filename);
		if($request->has('thumb'))		$this->view->thumb = trim($request->thumb);
		if($request->has('active'))		$this->view->active = ($request->active) ? 1 : 0;
		if($request->has('filename'))	$this->view->active_key = md5(trim($request->filename));
		
		if( $request->has('use_color') && $request->use_color=='yes' ){
			$this->view->use_color = 'yes';
			if( $request->has('color') && !empty($request->color) ){
				$Catalog = new CommerceMagentoCatalog();		// TO-DO un-hard-code this.
				$options = $Catalog->getProductAttributeOptions( 951, $this->locale_code );
				if( is_array($options) ){
					foreach( $options as $option ){
						if( $option['value']==$request->color ){
							$this->view->color = $request->color;
							$this->view->color_name = $option['label'];
							break;
						}
					}
				}
			}
		} else {
			$this->view->use_color = 'no';
		}
	}
	
	function awarditemAction(){
		$request = new Cts_Request($this->getRequest());
		if($request->has('title'))		$this->view->title = trim(urldecode($request->title));
		if($request->has('filename'))	$this->view->filename = trim(urldecode($request->filename));
		if($request->has('active'))	$this->view->active = ($request->active) ? 1 : 0;
		if($request->has('filename'))	$this->view->active_key = md5(trim($request->filename));
	}
	
	function relatedproductAction(){
		$request = new Cts_Request($this->getRequest());
		if($request->has('id'))		$this->view->id = trim($request->id);
		if($request->has('name'))	$this->view->name = trim(urldecode($request->name));
		if($request->has('sku'))	$this->view->sku = trim($request->sku);
	}
	
	function childproductAction(){
		$Catalog = new CommerceMagentoCatalog();
		$request = new Cts_Request($this->getRequest());
		$storeView = $this->locale_code;
		
		if( $request->has('parent_id') ){
			$this->view->id = chr(rand(65,90)).chr(rand(97,122)).chr(rand(65,90)).chr(rand(97,122)).chr(rand(65,90)).chr(rand(97,122)).chr(rand(65,90)).chr(rand(97,122));
			$this->view->sku	 		= urldecode($request->sku);
			$this->view->price 			= number_format(urldecode($request->price), 2, '.', '');
			$this->view->special_price	= (!empty($request->special_price)) ? number_format(urldecode($request->special_price), 2, '.', '') : '';
			$this->view->weight 		= number_format(urldecode($request->weight), 0, '', '');
			
			if( is_array($request->attributes) ){
				
				$product = $Catalog->getProduct( $request->parent_id, $storeView );		//dd($product);
				$attributes = $Catalog->getProductAttributes( $product['set'] );
				
				$simple_attributes = array();
				
				foreach( $request->attributes as $code=>$value ){
					foreach( $attributes as $attribute ){
						if( $attribute['code'] == $code ){
							$simple_attributes[$code]['code'] = $code;
							$simple_attributes[$code]['value'] = $value;
							$simple_attributes[$code]['label'] = $attribute['label'];
							$simple_attributes[$code]['type'] = $attribute['type'];
							
							if( $attribute['type']=='select' || $attribute['type']=='multiselect' ){
								$options = $Catalog->getProductAttributeOptions( $attribute['attribute_id'], $storeView );
					
								if(is_array($options)){
									foreach( $options as $option ){
										if( $option['value'] == $value ){
											$simple_attributes[$code]['value_string'] = $option['label'];
											break;
										}
									}
								}
							} else {
								if( $code=='bd_color_swatch_one' || $code=='bd_color_swatch_two' && !empty($value) ){
									$simple_attributes[$code]['value_string'] = str_replace('#','', strtolower($value) ); ## Normalize
								} else {
									$simple_attributes[$code]['value_string'] = $value;
								}
							}
							
							break;
						}
					}
				}
				//dd($simple_attributes);
				$this->view->attributes = $simple_attributes;
			}
		}
	}
	
	function searchAction() {
		$storeView = $this->locale_code;
		$Catalog = new CommerceMagentoCatalog();
		$request = new Cts_Request($this->getRequest());
		
		$filters = array();
		$filters['__no_children'] = true;
		
		if ( $request->has('name') ) {
			$filters['name'] = array( 'like' => "%{$request->name}%" );
		} elseif ( $request->has('sku') ) {
			$filters['sku'] = array( 'like' => "%{$request->name}%" );
		}
		
		$related_ids = array();
		$related = $Catalog->getRelatedProducts( $request->id );
		if ( is_array($related) ) {
			foreach ( $related as $rproduct ) {
				$related_ids[] = $rproduct['product_id'];
			}
		}
		
		$products = $Catalog->getProducts($filters, $storeView, null, array('attribute'=>'name', 'direction'=>'asc'));
		
		# Start XML return
		$dom = new DOMDocument();
		$dom->formatOutput = false;
		
		## Add printer information
		$root = $dom->createElement( 'results' );
		$dom->appendChild( $root );
		
		foreach ($products as $product) {
			$XMLProduct = $dom->createElement( 'product' );
			$XMLProduct->setAttribute( 'id', $product['product_id'] );
			$XMLProduct->setAttribute( 'name', $product['name'] );
			$XMLProduct->setAttribute( 'sku', $product['sku'] );

			if (in_array($product['product_id'], $related_ids)) {
				$XMLProduct->setAttribute('related', 'yes');
			} else {
				$XMLProduct->setAttribute('related', 'no');
			}

			$root->appendChild( $XMLProduct );
		}

		## Echo the XML
		header( "Content-type: text/xml" );
		echo $dom->saveXML();
		exit;
	}
	
	function testcurlAction(){
		$Cart = new Magento_Curl_Cart();
		$Cart->setLocale( $this->locale_code );
		$Cart->debug_mode = true;
		
		echo '<h1>Full Magento Cart Test</h1><br /><small>This will clear your cart.</small>';
		
		$Cart->getCartData();
		
		echo '<h3>Testing simple product addition</h3>';
		//dd( $Cart->addProduct( 287, 2, array(944=>533, 951=>124) ) );
		d( $Cart->addProduct(281, 3) );
		
		echo '<h3>Testing child product addition</h3>';
		d( $Cart->addProduct(288, 5) );
		
		echo '<h3>Testing removing a product from the cart</h3>';
		d( $Cart->removeProduct(288) );
		
		return;
	}
	
	function addTime( $seconds ){
		$exec_time = ini_get('max_execution_time')+$seconds;
		Cts_Log::report("Max Execution Time :: Extending execution time by {$seconds} seconds to {$exec_time} seconds", NULL, Zend_Log::INFO);
		set_time_limit($exec_time);
	}
	
	function fsort( $var, $order ){
		$order = array_reverse($order);
		foreach( $order as $key ){
			if( array_key_exists($key, $var) ){
				$tmp = $var[$key];
				unset($var[$key]);
				array_unshift($var, $tmp);
			}
		}
		return $var;
	}

}
